fn outsider() {
    println!("outsider fn!");
}
pub mod education {

    pub mod lean_rust {

        mod top_level {
            pub fn hi_there() {
                println!("hi there");
            }

            pub mod low_level {
                pub fn hello_world() {
                    println!("hello_world");
                }
            }
        }

        #[derive(Debug)]
        pub enum PersonId {
            // 括号里是和携带的数据的类型
            Passport(u32),
            UUID(String),
            IndentityCard(u32, u32, u32),
        }

        pub struct Person {
            pub name: String,
            last_name: String,
            age: u32,
            id: PersonId,
        }

        impl Person {
            // associated function
            // 这种方法适用于构造方法
            pub fn new() -> Person {
                Person {
                    name: "default".to_string(),
                    last_name: "default".to_string(),
                    age: 0,
                    id: PersonId::UUID("865fbd57-64b6-4064-8207-2368ead0436e".to_string()),
                }
            }

            pub fn from(name: String, last_name: String, age: u32, id: PersonId) -> Person {
                Person {
                    name,
                    last_name,
                    age,
                    id,
                }
            }

            pub fn name(&self) -> &String {
                &self.name
            }

            fn display(&self) {
                println!(
                    "{} {} {} {:?}",
                    self.name, self.last_name, self.age, self.id
                );
            }

            fn change_age(&mut self, new_age: u32) {
                self.age = new_age;
            }
        }
        /*
           感觉类似go的interface

           一组类型的通用接口。
           A trait就像数据类型可以实现的接口。
           当一个类型 实现一个特征，
           可以使用泛型将其抽象地视为该特征 或特质对象。
        */
        pub trait Log {
            fn display_info(&self);
            fn alert_something(&self) {
                println!("Default implementation~~~~~!")
            }
        }

        impl Log for Person {
            fn display_info(&self) {
                crate::outsider();
                super::super::outsider();

                println!(
                    "{} {} {} {:?}",
                    self.name, self.last_name, self.age, self.id
                );
            }
        }

        pub struct Animal(pub String);

        impl Log for Animal {
            fn display_info(&self) {
                println!("{}", self.0);
            }

            fn alert_something(&self) {
                println!("Animal implementation~~~~~!")
            }
        }

        pub fn log_info(val: impl Log) {
            val.alert_something();
        }

        // 编译之后占空间更小,但是功能比较少
        pub fn log_info_2(val: &dyn Log) {
            val.alert_something();
        }
    }
}
